﻿#include "TextOutScenePrintFunction.h"

#include <QTextDocument>
#include <QTextBlock>
#include <QDateTime>

#include "TextOutSceneWidget.h"
#include "../TableInScene/VectorInterface.h"

class TextOutScenePrintFunction::TextOutScenePrintFunctionPrivate :QObject
{
public:
	int in_params[2];
	int out_params[1];
	int in_count;
	int out_count;
public:
	TextOutScenePrintFunctionPrivate(QObject*parent) :QObject(parent)
	{
		in_count = 2;
		out_count = 1;

		in_params[0] = FPT_PTR;
		in_params[1] = FPT_NONE;
		out_params[0] = FPT_VOID;
	}

};
TextOutScenePrintFunction::TextOutScenePrintFunction(QObject *parent)
	: QObject(parent), private_ptr(new TextOutScenePrintFunctionPrivate(this))
{
}

TextOutScenePrintFunction::~TextOutScenePrintFunction()
{
}

static int TextOutScenePrint_FUNCTION(struct variant_s *in, int in_count, struct variant_s *out, void*tag)
{
	if (2 > in_count)
		return ERR_PARAM_NOT_MATCH;

	if (VALUETYPE_VOID_PTR != in[0].type)
		return ERR_DATATYPE_NOT_MATCH;
	if (nullptr == in[0].u.ptr)
		return ERR_DATATYPE_NOT_MATCH;

	TextOutSceneWidget*ptr = nullptr;
	//QTextDocument*doc = nullptr;

	try {
		AstScene*as = (AstScene*)in[0].u.ptr;
		ptr = dynamic_cast<TextOutSceneWidget*>(as->widget());
		//doc = ptr->textDocument();
	}
	catch (...) {
		//doc = nullptr;
	}

	if (nullptr == ptr)
		return -1;

	struct astring_s*str = nullptr;
	IVector*v = nullptr;
	QVector<QVariant>*vd = nullptr;
	QString msg;
	for (int i = 1; i < in_count; i++) {
		if (in[i].type & VALUETYPE_PTR) {
			msg += QString("[%1]").arg((qulonglong)(ulong*)in[i].u.ptr, 8, 16, QLatin1Char('0')).toUpper();
			continue;
		}
		else if (in[i].type & VALUETYPE_ARRAY) {
			v = (IVector*)in[i].u.ptr;
			vd = v->data();

			msg += QString("[%1]").arg(vd->count());
			for (int i = 0; i < vd->count(); i++) {
				if (i)
					msg += ",";
				const QVariant& vt = vd->operator[](i);
				switch (vt.type()) {
				case QVariant::Type::Double:
					msg += QString::number(vt.toDouble(), 'f');
					break;
				case QVariant::Type::String:
					msg += vt.toString();
					break;
				case QVariant::Type::Int:
					msg += QString::number(vt.toInt());
					break;
				case QVariant::Type::UInt:
					msg += QString::number(vt.toUInt());
					break;
				case QVariant::Type::Invalid:
					break;
				case QVariant::Type::LongLong:
					msg += QString::number(vt.toLongLong());
					break;
				case QVariant::Type::ULongLong:
					msg += QString::number(vt.toULongLong());
					break;
				case QVariant::Type::Time:
					msg += vt.toTime().toString("hh::mm::ss");
					break;
				case QVariant::Type::Date:
					msg += vt.toDate().toString("yyyy-MM-dd");
					break;
				case QVariant::Type::DateTime:
					msg += vt.toDate().toString("yyyy-MM-dd hh::mm::ss");
					break;
				}
			}
			continue;
		}
		switch (in[i].type) {
		case VALUETYPE_DOUBLE:
			msg += QString::number(in[i].u.d, 'f');
			break;
		case VALUETYPE_INTEGER:
			msg += QString::number(in[i].u.i);
			break;
		case VALUETYPE_STRING:
			str = (struct astring_s*)in[i].u.ptr;
			msg += str->value;//(char*)in[i].u.ptr;
			break;
		//case VALUETYPE_ARRAY:
		//	v = (IVector*)in[i].u.ptr;
		//	vd = v->data();

		//	msg += QString("[%1]").arg(vd->count());
		//	for (int i = 0; i < vd->count(); i++) {
		//		if (i)
		//			msg += ",";
		//		const QVariant& vt = vd->operator[](i);
		//		switch (vt.type()) {
		//		case QVariant::Type::Double:
		//			msg += QString::number(vt.toDouble(), 'f');
		//			break;
		//		case QVariant::Type::String:
		//			msg += vt.toString();
		//			break;
		//		case QVariant::Type::Int:
		//			msg += QString::number(vt.toInt());
		//			break;
		//		case QVariant::Type::UInt:
		//			msg += QString::number(vt.toUInt());
		//			break;
		//		case QVariant::Type::Invalid:
		//			break;
		//		case QVariant::Type::LongLong:
		//			msg += QString::number(vt.toLongLong());
		//			break;
		//		case QVariant::Type::ULongLong:
		//			msg += QString::number(vt.toULongLong());
		//			break;
		//		case QVariant::Type::Time:
		//			msg += vt.toTime().toString("hh::mm::ss");
		//			break;
		//		case QVariant::Type::Date:
		//			msg += vt.toDate().toString("yyyy-MM-dd");
		//			break;
		//		case QVariant::Type::DateTime:
		//			msg += vt.toDate().toString("yyyy-MM-dd hh::mm::ss");
		//			break;
		//		}
		//	}

		//	break;
		default:
			msg += "[unknown]";
			break;
		}
	}

	ptr->appendText(msg);
	if (out) {
		out->type = VALUETYPE_VOID;
	}

	return 0;
}

AstFunction* TextOutScenePrintFunction::operator()()
{
	return dynamic_cast<AstFunction*>(this);
}

QString TextOutScenePrintFunction::name()
{
	return "TextOutScenePrint";
}
int* TextOutScenePrintFunction::outputTypes()
{
	return private_ptr->out_params;
}
int TextOutScenePrintFunction::outputCount()
{
	return private_ptr->out_count;
}
int* TextOutScenePrintFunction::inputTypes()
{
	return private_ptr->in_params;
}
int TextOutScenePrintFunction::inputCount()
{
	return private_ptr->in_count;
}
void* TextOutScenePrintFunction::function()
{
	return TextOutScenePrint_FUNCTION;
}
